function clone(obj) {
	let buf;
	if (obj instanceof Array) {
		buf = [];
		let i = obj.length;
		while (i--) {
			buf[i] = clone(obj[i]);
		}
		return buf;
	} else if (obj instanceof Object) {
		buf = {};
		for (let k in obj) {
			buf[k] = clone(obj[k]);
		}
		return buf;
	} else {

		return obj;
	}

}
module.exports = class PublicModel {

	constructor(_db, table, docId) {
		this._table = table;
		this._docId = docId;
		this._db = _db || uniCloud.database();
		this._dbCmd = this._db.command;
		this._$ = this._dbCmd.aggregate;
		if(this._table){
			this._collection = this._db.collection(this._table);
		}
	}
	// 装载数据
	async load() {
		const cmd = await this._db.collection(this._table).doc(this._docId);
		if (cmd.data) {
			for (let key in cmd.data[0]) {
				if (key != undefined && key != null) {
					this[key] = cmd.data[0][key];
				}
			}
		}
	}
	// 更新
	async preservation(except = {}) {
		const getNeatInstance = this.getNeatInstance();
		console.log("PublicModel preservation begin");
		//如果没有则先set
		const cmd = await this._db.collection(this._table).doc(this._docId).get();
		if (!cmd.data || cmd.data.length <= 0) {
			await this._db.collection(this._table).doc(this._docId).set(getNeatInstance);
			return;
		}
		//有则更新，但需克隆
		const data = clone(getNeatInstance);
		//去除不需要更新字段
		for (let key in except) {
			if (key != undefined && key != null) {
				delete data[key];
			}
		}
		await this._db.collection(this._table).doc(this._docId).update(data);
		console.log("PublicModel preservation update end");
	}

	// 新增
	async add() {

		const instance = this.getNeatInstance();
		try {
			//阿里云
			await this._db.collection(this._table).add(instance);
		} catch (e) {
			//腾讯云
			await this._db.createCollection(this._table);
			await this._db.collection(this._table).add(instance);
		}

	}

	// 删除
	async remove() {
		await this._db.collection(this._table).doc(this._docId).remove();
	}
	// 删除全部 
	async removeAll() {

	 return	await this._db.collection(this._table).where({
			_id: this._dbCmd.exists(true)
		}).remove();
	}
	// 返回影子实例
	getNeatInstance() {
		const data = {};
		for (let key in this) {
			if (key.substring(0, 1) != "_") {
				data[key] = this[key]
			}
		}
		return data;
	}

	//批量新增
	async insert(data) {
		return await this._collection.add(data);
	}
	
	//批量更新
	async update(query = {} , data = {}){
		 return await this._collection.where(query).update(data)
	}


}
